<template>
  <el-main class="audio-main">

    <div id="welcome" class="welcome-info">
      <img :src="imgSrc" class="head-bg" width="100%" height="100%" alt="" />
      <div class="headLine">
        <div class="headLine-head">
          自动摘要
        </div>
        <div class="headLine-info">
          基于机器学习的自动摘要系统，可自动抽取输入文件中的关键信息，生成短文本摘要。可用于新闻摘要、语音摘要等场景。
        </div>
        <el-button class="headLine-to-more"  @click="clickHerf('#moreInfo')">了解更多</el-button>
        <el-button class="headLine-to-use" type="primary" @click="clickHerf('#fileMain')">立即使用</el-button>
      </div>
    </div>

    <div id="moreInfo" class="more-info">
      <div class="more-info-inside">
        <div class="more-info-title">
          功能介绍
        </div>
        <div class="more-info-left">
          <div v-for="(item, index) in moreInfo" :key="index" class="more-info-list">
            <div class="more-info-icon"><i class="el-icon-check"></i></div>
            <div class="more-info-words">{{ item }}</div>
          </div>
        </div>
        <div class="more-info-middle"></div>
        <el-collapse class="audio-main-collapse" v-model="activeName" accordion >
          <el-collapse-item title="TextRank算法" name="1">
            <div>TextRank 算法是一种用于文本的基于图的排序算法。其基本思想来源于谷歌的 PageRank 算法, 通过把文本分割成若干组成单元(单词、句子)并建立图模型, 利用投票机制对文本中的重要成分进行排序</div>
          </el-collapse-item>
          <el-collapse-item title="MMR 最大边界相关算法" name="2">
            <div>MMR(Maximal Marginal Relevance)，MMR 算法又叫最大边界相关算法，此算法在设计
             之初是用来计算 Query 文本与被搜索文档之间的相似度，然后对文档进行 rank 排序的算法。</div>
          </el-collapse-item>
          <el-collapse-item title="TextRank+Word2Vec 算法" name="3">
            <div>Word2Vec是一种深度学习的模型, 基于人工神经网络, 通过多层感知机将初始的底层特征组合为更抽象的高层特征, 并将高层特征用于普通的机器学习方法以得到更好的效果。</div>
          </el-collapse-item>
        </el-collapse>
      </div>
    </div>

    <div class="divider-before-file"></div>

    <div id="fileMain" class="file-handle" v-loading="loading" element-loading-background="rgba(255,255,255, 0.8)">
<!--      <vue-canvas-nest :config="configBg"></vue-canvas-nest>-->
      <div class="file-handle-title">功能展示</div>
      <el-button class="to-top-info" @click="clickHerf('#welcome')" icon="el-icon-caret-top" circle></el-button>
      <div class="file-select">
        <div class="tip" style="font-size: 15px;font-weight: bold">选择文件：</div>
        <input id="file" ref="fileUpload" type="file" title="请选择文件" value="请选择文件" @change="fileChange()">
        <el-button size="small" @click="clickToSubmit">上传</el-button>
      </div>

      <div class="audio-main-method-select">
        <el-select size="small"  v-model="rankMethod" placeholder="请选择摘要算法">
          <el-option
              v-for="item in options"
              :key="item.value"
              :label="item.label"
              :value="item.value">
          </el-option>
        </el-select>
        <el-button size="small" class="audio-main-method-select-btn" type="primary" @click="clickToHandle()">确定</el-button>
      </div>

      <div class="audio-main-text">
        文件读取结果：
        <el-input
            class="audio-main-text-input"
            type="textarea"
            :autosize="{ minRows: 18, maxRows: 18}"
            placeholder="请上传文件"
            v-model="textarea1">
        </el-input>
      </div>

      <div class="audio-main-text2">
        提取结果：
        <el-input
            class="audio-main-text2-input"
            type="textarea"
            :autosize="{ minRows: 18, maxRows: 18}"
            placeholder="请选择提取算法"
            v-model="textarea2">
        </el-input>
      </div>
    </div>


  </el-main>
</template>

<script>
import {handleOrigin} from "@/api/handleOrigin";
import axios from 'axios';

export default {
  name: "Audio",
  components: {},
  props: ["userInfo"],
  data() {
    return {
      imgSrc: require('../../assets/BgHead.jpg'),
      configBg: {
        color: '0,0,0',
        opacity: 0.7,
        zIndex: -2,
        count: 200,
      },
      activeName: '1',
      options: [{
        value: 'textRank',
        label: 'Text Rank算法'
      }, {
        value: 'mmr',
        label: 'MMR 最大边界相关算法'
      }, {
        value: 'word2vec',
        label: 'Text Rank+Word2Vec 算法'
      }],
      rankMethod: '',
      textarea1: '',
      textarea2: '',
      resultData: null,
      loading: false,
      fileList: [],
      fileType: "audio/*",
      fileTypeArr: ["wav", "flac", "opus", "m4a", "mp3", "jpg", "png", "bmp"],
      picTypeArr: ["jpg", "png", "bmp"],
      audioTypeArr: ["wav", "flac", "opus", "m4a", "mp3"],
      moreInfo: [
          "根据用户需求灵活自动抽取关键信息，形成摘要结果。本系统可用文本内容摘要语音内容摘要等多种应用",
          "结合传统语义特征和机器学习模型，准确计算语句的重要性，对文本内容进行全面分析",
          "可处理多种类型文件：语音、文字、图片等"],
    }
  },
  methods: {
    clickHerf(target){
      document.querySelector(target).scrollIntoView({
        block: 'start',
        behavior: 'smooth'
      });
    },
    fileChange () {
      let file = this.$refs.fileUpload.files[0]
      let fileName = file.name
      let fileType = fileName.substring(fileName.indexOf(".")).substring(1)
      if (!this.fileTypeArr.includes(fileType)) {
        this.$message({
          message: "不支持该文件类型",
          type: 'error',
          offset: 70,
          center: true
        });
      } else {
        this.$message({
          message: "上传的文件类型为"+fileType,
          type: 'warning',
          offset: 70,
          center: true
        });
      }

    },
    clickToSubmit() {
      if (this.$refs.fileUpload.files[0] == null) {
        this.$message({
          message: "文件为空",
          type: 'error',
          offset: 70,
          center: true
        });
        return
      } else {
        let fileName = this.$refs.fileUpload.files[0].name
        let fileType = fileName.substring(fileName.indexOf(".")).substring(1)
        let name = fileName.substring(0, fileName.indexOf("."))
        if (!this.fileTypeArr.includes(fileType)) {
          this.$message({
            message: "不支持该文件类型",
            type: 'error',
            offset: 70,
            center: true
          });
          return
        }
        if (name.length < 3) {
          this.$message({
            message: "文件名长度不能小于三个字符",
            type: 'error',
            offset: 70,
            center: true
          });
          return
        }
      }
      let fileName = this.$refs.fileUpload.files[0].name
      let fileType = fileName.substring(fileName.indexOf(".")).substring(1)
      let handleType = ""
      if (this.picTypeArr.includes(fileType)) {
        handleType = "pic"
      }
      if (this.audioTypeArr.includes(fileType)) {
        handleType = "audio"
      }
      if (handleType == "audio") {
        this.$confirm('音频文件的解析时间由音频的时长和文件大小决定，可能需要等待较长时间(1分30秒的音频大约需要15秒)', '注意', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.submit(handleType)
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消文件解析',
            offset: 70,
            center: true
          });
        });
      } else {
        this.submit(handleType)
      }
    },
    submit(handleType) {
      this.loading = true
      let formData = new window.FormData()
      let userName = (this.userInfo.userName == undefined) ? null : this.userInfo.userName
      formData.append('fileType', handleType)
      formData.append('file', document.querySelector('input[type=file]').files[0])
      formData.append('userName', userName)
      axios({
        url: 'https://yj1211.work/api/fileToWords',   //****: 你的ip地址
        data: formData,
        method: 'post',
        headers: {
          'Content-Type': 'multipart/form-data',
          // 'Access-Control-Allow-Origin': 'http://127.0.0.1:8081'
          //这里是为了解决跨域问题，但是博主并没有用这种方式解决。后面会给出解决方案
        }
      }).then((res) => {
        this.loading = false
        if (res.data.code === 200) {
          this.$emit("addHistory", res.data.data.fileHistory)
          if (handleType == "audio") {
            let resultArr =  eval('(' + res.data.data.result + ')');
            let result = ""
            for (let i = 0; i < resultArr.length; i++) {
              console.log(resultArr[i])
              result = result + resultArr[i].onebest
            }
            this.textarea1 = result
            this.textarea2 = ""
          }
          if (handleType == "pic") {
            this.textarea1 = res.data.data.result
            this.textarea2 = ""
          }
        }
        if (res.data.code === 400) {
          let resultArr =  eval('(' + res.data.message + ')');
          this.$message({
            message: resultArr.failed,
            type: 'warning',
            offset: 70,
            center: true
          });
        }

      }) // 发送请求
    },
    clickToHandle() {
      if (this.rankMethod.trim() == '') {
        this.$message({
          message: '请选择一种摘要算法',
          type: 'warning',
          offset: 70,
          center: true
        });
        return
      }
      if (this.textarea1.trim() == '') {
        this.$message({
          message: '处理内容不能为空',
          type: 'warning',
          offset: 70,
          center: true
        });
        return
      }
      if (this.rankMethod.trim() == 'word2vec') {
        this.$confirm('word2vec需要加载模型进行计算，大约需耗时20秒左右，是否继续进行摘要', '注意', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.handleOrigin()
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消摘要',
            offset: 70,
            center: true
          });
        });
      } else {
        this.handleOrigin()
      }
    },
    handleOrigin() {
      this.loading = true
      handleOrigin(this.rankMethod, this.textarea1)
        .then(response => {
          let data = response.data
          if(data.code == 200) {
            this.$message({
              message: '处理成功',
              type: 'success',
              offset: 70,
              center: true
            });
            let result = ''
            let resultDate = data.data
            this.resultData = resultDate
            if (this.rankMethod == "textRank") {
              let keyWord = resultDate.keyWord
              result = result + "关键字："
              keyWord.forEach((item)=>{
                result = result + item + "    "
              })
              result = result + "\r"
              let keySentence = resultDate.keySentence
              result = result + "关键短语："
              keySentence.forEach((item)=>{
                result = result + item + "    "
              })
              result = result + "\r"
              let abstract = resultDate.abstract
              result = result + "摘要："
              abstract.forEach((item)=>{
                result = result + item + "  "
              })
              result = result + "\r"
            }
            if (this.rankMethod == "mmr") {
              resultDate.forEach((item,index)=>{
                result = result + (index+1) + "、" + item.trim() + "\r\r"
              })
            }
            if (this.rankMethod == "word2vec") {
              resultDate.forEach((item,index)=>{
                result = result + (index+1) + "、" + item.trim() + "\r\r"
              })
            }
            this.textarea2 = result
          }
          if(data.code == 400) {
            this.$message({
              message: data.message,
              type: 'error',
              offset: 70,
              center: true
            });
          }
          this.loading = false
        })
    },
    text1(msg) {
      this.textarea1 = msg
      this.textarea2 = ""
    },

  },
  activated() {

  },
}
</script>

<style scoped>
.audio-main{
  height: 100%;
  width: 100%;
  position: relative;
}
.audio-main-collapse{
  position: absolute;
  top: 70px;
  width: 400px;
  left: 55%;
}
.audio-main-method-select{
  position: absolute;
  top: 23%;
  left: 55%;
}
.audio-main-method-select-btn{
  margin-left: 10px;
}
.audio-main-text{
  width: 45%;
  position: absolute;
  top: 35%;
  left: 4%;
  font-weight: bold;
  font-size: 15px;
}
.audio-main-text-input{
  margin-top: 10px;
  overflow: auto;
}
.audio-main-text2{
  width: 45%;
  position: absolute;
  top: 35%;
  left: 53%;
  font-weight: bold;
  font-size: 15px;
}
.audio-main-text2-input{
  margin-top: 10px;
}
.el-collapse-item /deep/ .el-collapse-item__header{
  font-size: 18px;
  font-weight: normal;
  background-color: rgba(255,255,255,0.7);
}
.el-collapse-item /deep/ .el-collapse-item__wrap{
  font-weight: lighter;
  background-color: rgba(255,255,255,0.7);
}
.el-collapse-item /deep/ .el-collapse-item__content{
  font-size: 17px;
}
.file-select{
  position: absolute;
  top: 20%;
  left: 20%;
}
.welcome-info{
  position: relative;
  width: 100%;
  height: 400px;
}
.file-handle{
  width: 100%;
  position: relative;
  height: 800px;
}
.to-top-info{
  font-size: 30px;
  position: absolute;
  top: 20px;
  left: 20px;
}
.headLine{
  color: #eeeeee;
  position: relative;
  top: 50px;
  width: 500px;
  left: 20%;
}
.headLine-head{
  /*text-shadow: 1px 1px 0 #000000,-1px -1px 0 #000,-1px 1px 0 #000,1px -1px 0 #000;*/
  font-size: 50px;
  font-weight: normal;
  position: absolute;
  top: 0;
  width: 200px;
}
.headLine-info{
  /*text-shadow: 1px 1px 0 #000000,-1px -1px 0 #000,-1px 1px 0 #000,1px -1px 0 #000;*/
  line-height: 170%;
  position: absolute;
  top: 90px;
  width: 100%;
  font-size: 15px;
}
.headLine-to-more{
  position: absolute;
  top: 200px;
}
.more-info-to-use{
  position: absolute;
  bottom: 30px;
  left: 46.5%;
}
.headLine-to-use{
  position: absolute;
  top: 200px;
  left: 150px;
}
.more-info{
  position: relative;
  width: 100%;
  height: 450px;
  /*background-color: #999999;*/
}
.more-info-inside{
  position: relative;
  top: 20px;
  left: 10%;
  width: 80%;
  height: 400px;
}
.more-info-title{
  font-weight: bold;
  font-size: 25px;
  height: 25px;
  text-align: center;
}
.more-info-left{
  padding-top: 40px;
  position: absolute;
  top: 30px;
  height: 370px;
  width: 47%;
}
.more-info-middle{
  position: absolute;
  top: 50px;
  left: 49.7%;
  height: 320px;
  width: 1px;
  background-color: #8e8e8e;
}
.more-info-list{
  margin-bottom: 60px;
  margin-left: 60px;
  height: 60px;
}
.more-info-icon{
  float: left;
  width: 10%;
  font-size: 20px;
}
.more-info-words{
  float: left;
  line-height: 150%;
  width: 90%;
  font-size: 18px;
}
.file-handle-title{
  position: absolute;
  top: 40px;
  font-weight: bold;
  font-size: 27px;
  width: 100%;
  text-align: center;
}
.el-select /deep/ .el-input{
  width: 230px;
}
.el-select /deep/ .el-input__inner {
  background-color: rgba(255, 255, 255, 0.7);
}
.el-textarea /deep/ .el-textarea__inner {
  background-color: rgba(255, 255, 255, 0.7);
}
.head-bg{
  filter: blur(2px);
  z-index:-1;
  position: absolute;
}
.divider-before-file{
  width: 100%;
  height: 1px;
  background-color: #8e8e8e;
}

</style>
